package com.hxh.generater.springBoot.simple.gen.crud;

import com.hxh.config.Constants;
import com.hxh.entity.Project;
import com.hxh.entity.po.ClassInfo;
import com.hxh.entity.po.FieldName;
import com.hxh.generater.springBoot.util.ProcessWriteLine;
import com.hxh.util.GenUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.HashMap;
import java.util.Map;

/**
 * @ProjectName: AICode
 * @Package: com.hxh.generater
 * @Author: HXH
 * @Description:
 * @Date: 2023/11/28 15:08
 */
@Slf4j
public class GenDao {
    private static String generationDaoClassSelectById(ClassInfo classInfo) {
        String className = classInfo.getClassName();
        StringBuilder res = new StringBuilder("    " + className + " selectById(");
        StringBuilder params = new StringBuilder();
        for (FieldName fieldName : classInfo.getIdNameList()) {
            params.append("@Param(\"").append(fieldName.getJavaName()).append("\") ").append(fieldName.getJavaType()).append(" ").append(fieldName.getJavaName()).append(",");
        }
        if (params.length() > 0) {
            params.deleteCharAt(params.length() - 1);
        }
        res.append(params).append(");");
        return res.toString();
    }

    private static String generationDaoClassDeleteById(ClassInfo classInfo) {
        StringBuilder res = new StringBuilder("    int deleteById(");
        StringBuilder params = new StringBuilder();
        for (FieldName fieldName : classInfo.getIdNameList()) {
            params.append("@Param(\"").append(fieldName.getJavaName()).append("\") ").append(fieldName.getJavaType()).append(" ").append(fieldName.getJavaName()).append(",");
        }
        if (params.length() > 0) {
            params.deleteCharAt(params.length() - 1);
        }
        res.append(params).append(");");
        return res.toString();
    }

    public static void generationDaoClass(Project project, ClassInfo classInfo) throws IOException {
        generationDaoClass(project, classInfo, null);
    }

    public static String generationDaoClass(String packageName, ClassInfo classInfo) throws IOException {
        return generationDaoClass(null, classInfo, packageName);
    }

    public static String generationDaoClass(Project project, ClassInfo classInfo, String packageName) throws IOException {
        if (project == null && StringUtils.isBlank(packageName)) {
            log.error("generationDaoClass中，project参数和packageName参数不能同时为空!");
            throw new RuntimeException("generationDaoClass中，project参数和packageName参数不能同时为空!");
        }
        boolean returnModel = false;
        if (project == null) {
            returnModel = true;
        }

        String className = classInfo.getClassName();
        String daoName = className + "Dao";

        String daoTempName = daoName + ".Template";
        File tempClassFile;
        if (returnModel) {
            tempClassFile = File.createTempFile(daoName, ".Template");
        } else {
            tempClassFile = GenUtil.newFile(project, "dao", daoTempName);
        }

        StringBuilder importAddition = new StringBuilder();

        String selectById = generationDaoClassSelectById(classInfo);
        String deleteById = generationDaoClassDeleteById(classInfo);
        //先生成模板
        try {
            FileWriter fileWriter = new FileWriter(tempClassFile);
            BufferedWriter writer = new BufferedWriter(fileWriter);

            File template = new File(Constants.templatePathPrefix + "simple\\template\\daoTemplate");
            BufferedReader br = new BufferedReader(new FileReader(template));
            String line;

            Map<String, String> replaceWord = new HashMap<>();
            replaceWord.put("deleteById", deleteById);
            replaceWord.put("selectById", selectById);
            ProcessWriteLine processWriteLine = new ProcessWriteLine(replaceWord);

            while ((line = br.readLine()) != null) {
                processWriteLine.writeLine(line, writer);
            }
            br.close();

            //加上addition\\daoTemplateAddition文件下，与类名相同的文件夹下所有的文件
            File additionFile = new File(Constants.templatePathPrefix + "simple\\template\\addition\\daoTemplateAddition\\" + daoName);
            if (additionFile.exists() && additionFile.isDirectory()) {
                File[] additionFiles = additionFile.listFiles();
                if (additionFiles != null && additionFiles.length > 0) {
                    for (File file : additionFiles) {
                        br = new BufferedReader(new FileReader(file));
                        while ((line = br.readLine()) != null) {
                            ProcessWriteLine.processPerLine(line, importAddition, null, writer);
                        }
                        br.close();
                    }
                }
            }

            writer.newLine();
            writer.write("}");

            writer.close();
            fileWriter.close();
        } catch (Exception e) {
            e.printStackTrace();
        }


        try {
            BufferedWriter writer;
            FileWriter fileWriter = null;
            StringWriter stringWriter = null;
            if (returnModel) {
                stringWriter = new StringWriter();
                writer = new BufferedWriter(stringWriter);
            } else {
                File classFile = GenUtil.newFile(project, "dao", daoName);
                fileWriter = new FileWriter(classFile);
                writer = new BufferedWriter(fileWriter);
            }

            File template = tempClassFile;
            BufferedReader br = new BufferedReader(new FileReader(template));
            String line;

            Map<String, String> replaceWord = new HashMap<>();
            replaceWord.put("importAddition", importAddition.toString());
            replaceWord.put("className", className);
            replaceWord.put("daoName", daoName);
            replaceWord.put("GroupId", returnModel ? packageName : project.getBackendProject().getProjectGroup());
            ProcessWriteLine processWriteLine = new ProcessWriteLine(replaceWord);
            while ((line = br.readLine()) != null) {
                processWriteLine.writeLine(line, writer);
            }
            br.close();

            writer.close();
            if (fileWriter != null) {
                fileWriter.close();
            }
            String bakPath = tempClassFile.getAbsolutePath() + ".bak";
            File bakFile = new File(bakPath);
            if (tempClassFile.exists()) {
                tempClassFile.delete();
            }
            if (bakFile.exists()) {
                bakFile.delete();
            }
            if (returnModel) {
                return stringWriter.toString();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


}
